package com.cdeledu.thread4.c17;

/**包可见，创建时使用ReadWriterLock的create方法
 * @author HP
 *
 */
class ReadWriteLockImpl implements ReadWriteLock {
	
	/**虽然我们在开发一个读写锁，但是在实现的内部也需要一个锁进行数据同步以及线程之间的通信
	 * 
	 */
	private final Object MUTEX = new Object();
	/**当前有多少个线程正在写入
	 * 
	 */
	private int writingWriters = 0;
	/**当前有多少个线程正在等待写入
	 * 
	 */
	private int waitingWriters = 0;
	/**当前有多少个线程正在read
	 * 
	 */
	private int readingReaders = 0;
	/**控制倾向性，一般来说读写锁非常适用于读多写少的场景，如果preferWriter为false，很多读线程都在读数据，那么写线程将会很难得到写的机会
	 * 
	 */
	private boolean preferWriter;

	/**默认情况下perferWriter为true
	 * 
	 */
	public ReadWriteLockImpl() {
		this(true);
	}

	/**构造ReadWriteLockImpl并且传入preferWriter
	 * @param preferWriter
	 */
	public ReadWriteLockImpl(boolean preferWriter) {
		this.preferWriter = preferWriter;
	}

	@Override
	public Lock readLock() {
		return new ReadLock(this);
	}

	@Override
	public Lock writeLock() {
		return new WriteLock(this);
	}

	/**使写线程的数量增加
	 * 
	 */
	void incrementWritingWriters() {
		this.writingWriters++;
	}

	/**使等待写入的线程数量增加
	 * 
	 */
	void incrementWaitingWriters() {
		this.waitingWriters++;
	}

	/**使读线程的数量增加
	 * 
	 */
	void incrementReadingReaders() {
		this.readingReaders++;
	}

	/**使写线程的数量减少
	 * 
	 */
	void decrementWritingWriters() {
		this.writingWriters--;
	}

	/**使等待获取写入锁的数量减少
	 * 
	 */
	void decrementWaitingWriters() {
		this.waitingWriters--;
	}

	/**使读取线程的数量减少
	 * 
	 */
	void decrementReadingReaders() {
		this.readingReaders--;
	}

	@Override
	public int getWritingWriters() {
		return this.writingWriters;
	}

	@Override
	public int getWaitingWriters() {
		return this.waitingWriters;
	}

	@Override
	public int getReadingReaders() {
		return this.readingReaders;
	}

	Object getMutex() {
		return this.MUTEX;
	}

	boolean getPreferWriter() {
		return this.preferWriter;
	}

	/**设置写锁偏好
	 * @param preferWriter
	 */
	void changePrefer(boolean preferWriter) {
		this.preferWriter = preferWriter;
	}
	
}